package com.laijiale.util;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author laijiale
 * @date 2024年07月25日 10:08
 */

public   class JwtUtil {
    /**
     * JWT服务端密钥
     */
    private static final String SECRET_KEY = "my-secret";
    /**
     * JWT主题
     */
    private static final String SUBJECT = "用户登录认证";
    /**
     * JWT签发人
     */
    private static final String ISSUER = "LaiJiale";
    /**
     * JWT签发时间
     */
    private static final Date ISSUED_AT = new Date();
    /**
     * JWT过期时间
     */
    private static final Date EXPIRES_AT =
            new Date(System.currentTimeMillis() + (1000 * 60 * 60 * 2L));
    /**
     * JWT即将过期的时间阈值
     */
    private static final Long EXPIRATION_TIME_THRESHOLD = 1000 * 60 * 5L;
    /**
     * JWT即将过期的标记KEY
     */
    private static final String EXPIRING_SOON = "expiringSoon";

    public static String build(Long id , String name, String avatar) {
        if (ObjectUtil.hasNull(id, name, avatar)) {
            throw new RuntimeException("JWT存在null值负载");
        }
        JWTCreator.Builder builder = JWT.create();
        builder.withClaim("id", id);
        builder.withClaim("name", name);
        builder.withClaim("avatar", avatar);
        //保证Token一致性
        builder.withClaim("created",System.currentTimeMillis());
        builder.withSubject(SUBJECT);
        builder.withIssuer(ISSUER);
        builder.withIssuedAt(ISSUED_AT);
        builder.withExpiresAt(EXPIRES_AT);
        return builder.sign(Algorithm.HMAC256(SECRET_KEY));
    }
    public static Map<String, Object> verify(String token) {
        Map<String, Object> result = new HashMap<>(4);
        if (StrUtil.isEmpty(token)) {
            throw new RuntimeException("token令牌为空");
        }
        // 通过秘钥验证token字符串，验证失败直接抛出异常
        DecodedJWT decodedJwt = JWT.require(Algorithm.HMAC256(SECRET_KEY)).build().verify(token);

        Long id = decodedJwt.getClaim("id").asLong();
        String name = decodedJwt.getClaim("name").asString();
        String avatar = decodedJwt.getClaim("avatar").asString();

        // 判断Token是否即将过期
        if (decodedJwt.getExpiresAt().getTime() - System.currentTimeMillis()
                < EXPIRATION_TIME_THRESHOLD) {
            result.put(EXPIRING_SOON, true);
            result.put("newToken", build(id, name, avatar));
        } else {
            result.put("id", id);
            result.put("name", name);
            result.put("avatar", avatar);
            result.put(EXPIRING_SOON, false);
        }

        return result;

    }
    /**
     * 验证token字符串，验证失败直接抛出异常，成功返回id值
     *
     * @param token token字符串
     * @return 用户ID
     */
    public static Long getId(String token) {
        return (Long) verify(token).get("id");
    }
    }

